<?php
/**
 * @link https://gitee.com/toshcn/micro-hau
 * @copyright Copyright (c) 2022/4/20 micro-hau
 * @author toshcn <toshcn@foxmail.com>
 */

namespace api\controllers;

use Yii;
use yii\filters\auth\HttpBearerAuth;

/**
 * API项目认证类控制器 api项目需要用户登录的接口的控制器都要继承此类
 * Class AuthController
 * @package api\controllers
 */
class AuthController extends ApiController
{
    // 错误码 令牌无效
    const ERR_CODE_AUTHORIZATION_INVALID = 3002;
    // 错误码 未登录
    const ERR_CODE_NOT_LOGGED_IN = 3001;
    /**
     * 在请求动作前检测会员登录状态
     * @param mixed $action 当前请求的动作
     * @return bool
     * @throws \yii\web\BadRequestHttpException
     */
    public function beforeAction($action)
    {
        $res = parent::beforeAction($action);

        // 检测会员登录状态 如果用户未登录 取出请求标头 使用标头保存的token登录用户账号
        if ($res && Yii::$app->getUser()->isGuest) {
            $auth = new HttpBearerAuth();
            // 获取PHP请求标头：Authorization
            $authHeader = Yii::$app->getRequest()->getHeaders()->get($auth->header);
            if ($auth->pattern !== null) {
                // 用正则取出标头 保存在变量$matches中，$matches下标1为token的值
                if (preg_match($auth->pattern, $authHeader, $matches)) {
                    $authHeader = empty($matches[1]) ? false : $matches[1];
                    // 如果Authorization标头不为空，尝试用token登录用户账号
                    if ($authHeader && Yii::$app->getUser()->loginByAccessToken($authHeader, get_class($auth))) {
                        // 登录成功
                        return true;
                    }
                    // 登录令牌无效
                    Yii::$app->getResponse()->data = Yii::$app->api->error(
                        static::ERR_CODE_AUTHORIZATION_INVALID,
                        Yii::t('common', 'The Authorization is invalid.')
                    );
                    Yii::$app->getResponse()->send();
                    return false;
                }
            }
            // 未登录
            Yii::$app->getResponse()->data = Yii::$app->api->error(
                static::ERR_CODE_NOT_LOGGED_IN,
                Yii::t('common', 'Please login first.')
            );
            Yii::$app->getResponse()->send();
        }
        // 禁止未登录访问接口
        return false;
    }
}
